package table;

import java.util.ArrayList;

import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import columnEditors.ButtonEditor;
import columnEditors.ButtonRenderer;
import columnEditors.CheckBoxRenderer;
import columnEditors.JTableRenderer;
import columnEditors.MyComboBoxEditor;

import models.DBTableModel;
import quary.Quary;
import quary.QuaryBridge;
import quary.VinylData;
import quary.VinylDataVar;

public class MemberTable extends AbstractTable {
	
	private static final String[] COLUMN_IDENTIFIERS = {
		"*",
		"M ID", 
		"P ID",
		"Reg Dato", 
		"Stilling", 
		"Action"
	};
	
	private static final String[] COLUMN_NAMES = {
		VinylData.MEMBER_ID, 
		VinylData.MEMBER_PERSON_ID,
		VinylData.MEMBER_REG_DATE,
		VinylData.MEMBER_POSITION, 
	};
	
	private QuaryBridge quaryBridge;
	private JTableRenderer tableRenderer;

	public MemberTable(JScrollPane contentPane, QuaryBridge quaryBridge) {
		super(contentPane);
		
		this.quaryBridge = quaryBridge;
		
		this.setColumnSelectionAllowed(true);
		this.setRowSelectionAllowed(true);
	
		this.tableRenderer = new JTableRenderer();
		DefaultTableModel tableModel = new DBTableModel(tableRenderer, 4);
		
		this.setTableRenderer(tableRenderer);
		this.setTableModel(tableModel);
		
	}
	
	@Override
	public void activate() {
		super.activate();
		
		this.populate();
	}
	
	@Override
	public void deactivate() {
		super.deactivate();
		
		this.tableRenderer.clearCommitedCells();
		this.tableRenderer.clearEditedCells();
	}
	
	@Override 
	protected void populate() {
		Object[][] data = 
			this.quaryBridge.getTableData(VinylDataVar.MEMBER, VinylDataVar.MEMBER_ID);
		
		data = this.addActionColumnsToArray(data);
		this.setData(data, COLUMN_IDENTIFIERS);
		
		this.setupColumns();
		
		this.addInsertionRow();
	}
	
	private void setupColumns() {
		this.setupDropDownColumns();
		this.setupCheckBoxColumns();
		this.setupButtonColumns();
	}
	
	private void setupDropDownColumns() {
		Object[] memberIDArray = quaryBridge.getKeysFrom(VinylDataVar.MEMBER, VinylDataVar.MEMBER_ID);
		Object[] memberPersonIDArray = quaryBridge.getKeysFrom(VinylDataVar.MEMBER , VinylDataVar.MEMBER_PERSON_ID);
		Object[] personIDArray = quaryBridge.getKeysFrom(VinylDataVar.PERSON , VinylDataVar.PERSON_ID);
		
		ArrayList<Object> tempArray = new ArrayList<Object>();
		for (int i = 0; i < memberPersonIDArray.length; i++) {
			tempArray.add(memberPersonIDArray[i]);
		}
		
		ArrayList<Object> temp2Array = new ArrayList<Object>();
		temp2Array.add(Quary.NULL);
		
		for (int i = 0; i < personIDArray.length; i++) {
			if (!tempArray.contains(personIDArray[i]))
				temp2Array.add(personIDArray[i]);
		}
		
		memberPersonIDArray = temp2Array.toArray();
		
		
		this.getColumn("M ID").setCellEditor(new MyComboBoxEditor(new JComboBox(memberIDArray)));
		this.getColumn("P ID").setCellEditor(new MyComboBoxEditor(new JComboBox(memberPersonIDArray)));
	}
	
	private void setupCheckBoxColumns() {
		TableColumn tableColumn = this.getColumn("*");
		tableColumn.setCellRenderer(new CheckBoxRenderer());
		tableColumn.setCellEditor(new DefaultCellEditor(new JCheckBox()));
		tableColumn.setPreferredWidth(30);
	}
	
	private void setupButtonColumns() {
		TableColumn tableColumn = this.getColumn("Action");
		tableColumn.setCellRenderer(new ButtonRenderer());
		tableColumn.setCellEditor(new ButtonEditor(this));
	}
	
	private Object[][] addActionColumnsToArray(Object[][] data) {
		Object[][] newData = new Object[data.length][data[0].length +2];
		
		for (int r = 0; r < newData.length; r++) {
			for (int c = 0; c < newData[r].length; c++) {
				if (c == 0) {
					newData[r][c] = false;
				}
				else if (c == newData[r].length -1) {
					newData[r][c] = "Update";
				}
				else {
					newData[r][c] = data[r][c-1];
				}
			}
		}
		
		return newData;
	}
	
	private void addInsertionRow() {
		int columnCount = this.getColumnCount();
		int id = (Integer) this.getValueAt(this.getRowCount() -1, 1);
		
		Object[] newRow = new Object[columnCount];
		newRow[0] = false;
		newRow[1] = id +1;
		newRow[columnCount - 1] = "Insert";
			
		this.addRow(newRow);
		this.requestFocus();
		this.selectAndEditCellAt(this.getRowCount() -1, 2, true);
		this.setValueAt("Update", this.getRowCount() -2, columnCount -1);
	}
	
	public boolean isRowChecked(int row) {
		return (Boolean) this.getValueAt(row, 0);
	}
	
	@Override
	public int getTableID() {
		// TODO Auto-generated method stub
		return 0;
	}
	
	@Override
	protected Object[] getDataAtRow(int row) {
		int columnCount = this.getColumnCount();

		Object[] data = new Object[columnCount - 2];
		
		for (int i = 0; i < data.length; i++) {
			data[i] = this.getValueAt(row, i+1);
		}
		
		return data;
	}

	@Override
	public int insertLastRowToDatabase() {
		Object[] rowData = this.getDataAtRow(this.getRowCount() - 1);
		
		int affected = this.quaryBridge.insertIntoDatabase(VinylData.MEMBER, COLUMN_NAMES, rowData);
		if (affected > 0) {
			this.tableRenderer.addCommitedRow(this.getRowCount() -1);
			this.updateTable();
			((MyComboBoxEditor)this.getColumn("P ID").getCellEditor()).getComboBox().removeItem(rowData[1]);
			this.addInsertionRow();
		}
			
		
		return affected;
	}
	
	@Override
	public int deleteSelectedRowsFromDatabase() {
		ArrayList<Object> keys = new ArrayList<Object>();
		ArrayList<Integer> rows = new ArrayList<Integer>();
	
		//What rows are to be deleted
		for (int i = 0; i < this.getRowCount(); i++) {
			if ((Boolean) this.getValueAt(i, 0)) {
				keys.add(this.getValueAt(i, 1));
				rows.add(i);
			}
		}
		
		int affected = 0;
		
		if (rows.size() > 0) {
			this.clearSelection();
			this.removeRow(this.getRowCount() -1);
			
			//Delete the rows from the database
			if (keys.size() != 0) {
				affected = quaryBridge.deleteFromDatabase(VinylData.MEMBER, VinylData.MEMBER_ID, keys.toArray());
			}
			
			if (affected > 0) {
				for (int i = rows.size() -1; i >= 0 ; i--) {
					((MyComboBoxEditor)this.getColumn("P ID").getCellEditor()).getComboBox().addItem(this.getValueAt(rows.get(i), 2));
					
				}
				//Delete the rows from the visual tabel
				for (int i = rows.size() -1; i >= 0 ; i--)
					this.removeRow(rows.get(i));
			}
			
			//Add updated insertion row
			this.addInsertionRow();
		}
		
		return affected;
	}

	@Override
	public int updateRowInDatabase(int row) {
		Object[] data = this.getDataAtRow(row);
		Object[] keyArray = {
				this.getValueAt(row, 1)
		};
		
	
		
		int affected = quaryBridge.updateRowInDatabase(
				VinylData.MEMBER, COLUMN_NAMES, data, VinylData.MEMBER_ID, keyArray);
		if (affected > 0) {
			this.tableRenderer.addCommitedRow(row);
			this.updateTable();
		}
			
		
		
		return affected;
	}
}
